package cn.ydxlm.maplib.widget;

import android.content.Context;
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.FrameLayout;

import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.model.BitmapDescriptor;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.CameraPosition;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.Polyline;
import com.amap.api.maps.model.PolylineOptions;
import cn.ydxlm.maplib.R;
import cn.ydxlm.maplib.entity.LatLon;
import cn.ydxlm.maplib.entity.Location;
import cn.ydxlm.maplib.entity.Marker;

import java.util.ArrayList;
import java.util.List;

public class MapView extends FrameLayout {
    private static final String TAG = "MapView";
    private com.amap.api.maps.MapView mMapView;
    private BitmapDescriptor searchBdA;
    private MarkerOptions positionOptions;
    private OnMarkerClickListener mOnMarkerClickListener;
    private OnMapClickListener mOnMapClickListener;
    private OnZoomLevelListener mZoomLevelListener;
    private List<BitmapDescriptor> cacheBitmap = new ArrayList<>();
    private List<com.amap.api.maps.model.Marker> mMarkers = new ArrayList<>();
    private int lastClick;//最后一次选中的点
    private int iconP;
    private int iconN;
    private int lastZoom;

    public MapView (Context context) {
        super(context);
        init(context);
    }

    public MapView (Context context, AttributeSet attributeSet) {
        super(context, attributeSet);
        init(context);
    }

    public MapView (Context context, AttributeSet attributeSet, int i) {
        super(context, attributeSet, i);
        init(context);
    }

    private void init (Context context) {
        searchBdA = BitmapDescriptorFactory.fromResource(R.drawable.map_position_icon);
        mMapView = new com.amap.api.maps.MapView(context);
        mMapView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
        addView(mMapView);
        mMapView.getMap().setOnCameraChangeListener(new AMap.OnCameraChangeListener() {
            @Override
            public void onCameraChange (CameraPosition cameraPosition) {
            }

            @Override
            public void onCameraChangeFinish (CameraPosition cameraPosition) {
                final int zoom = (int) (int) cameraPosition.zoom;
                if (mZoomLevelListener != null && Math.abs(zoom - lastZoom) > 1) {
                    Log.i(TAG, "zoom change:" + zoom);
                    lastZoom = zoom;
                    mZoomLevelListener.onZoomChange(zoom, cameraPosition.target.latitude, cameraPosition.target.longitude);
                }
            }
        });
        setZoomLevel(18f);
//        mMapView.showZoomControls(false);
        mMapView.getMap().setMyLocationEnabled(false);

        mMapView.getMap().setOnMarkerClickListener(new AMap.OnMarkerClickListener() {
            @Override
            public boolean onMarkerClick (com.amap.api.maps.model.Marker marker) {
                if (mOnMarkerClickListener == null) {
                    return false;
                }
                mOnMarkerClickListener.onMarkerClick(mMarkers.indexOf(marker));
                final BitmapDescriptor bitmapDescriptor2 = BitmapDescriptorFactory.fromResource(iconN);
                cacheBitmap.add(bitmapDescriptor2);
                mMarkers.get(lastClick).setIcon(bitmapDescriptor2);
                lastClick = mMarkers.indexOf(marker);
                final BitmapDescriptor bitmapDescriptor1 = BitmapDescriptorFactory.fromResource(iconP);
                cacheBitmap.add(bitmapDescriptor1);
                marker.setIcon(bitmapDescriptor1);
                return true;
            }
        });
        mMapView.getMap().setOnMapClickListener(new AMap.OnMapClickListener() {
            @Override
            public void onMapClick (LatLng latLng) {
                if (mOnMapClickListener != null) {
                    mOnMapClickListener.OnMapClick(latLng.latitude, latLng.longitude);
                }
            }
        });
    }


    public void setLocationIcon (int resId) {
        searchBdA = BitmapDescriptorFactory.fromResource(resId);
    }

    public void setOnMapClickListener (OnMapClickListener onMapClickListener) {
        mOnMapClickListener = onMapClickListener;
    }

    /**
     * 设置地图中心点
     *
     * @param latitude
     * @param longitude
     */
    public void setCenterPoint (double latitude, double longitude) {
        Log.i(TAG, "setCenterPoint");
        LatLng center = new LatLng(latitude, longitude);
//        MapStatusUpdate status = MapStatusUpdateFactory.newLatLng(center);
//        mMapView.getMap().animateMapStatus(status);
        mMapView.getMap().animateCamera(CameraUpdateFactory.newLatLng(center));
//        map1.getMapView().setLogoPosition(LogoPosition.logoPostionleftTop);//设置logo位置
    }

    public void setCenterPoint (Location location) {
        setCenterPoint(location.getLatitude(), location.getLongitude());
        if (searchBdA == null) {
            searchBdA = BitmapDescriptorFactory.fromResource(R.drawable.map_position_icon);
        }
        positionOptions = new MarkerOptions()
                .icon(searchBdA).position(new LatLng(location.getLatitude(), location.getLongitude()));
        mMapView.getMap().clear();
        mMapView.getMap().addMarker(positionOptions);
    }


    public void addMarker (final List<Marker> markerList, final int iconN, final int iconP) {
        Log.i(TAG, "addMarker:" + markerList.size());
        this.iconN = iconN;
        this.iconP = iconP;
        for (BitmapDescriptor descriptor : cacheBitmap) {
            descriptor.getBitmap().recycle();
            descriptor.recycle();
        }
        final ArrayList<MarkerOptions> list = new ArrayList<>();
        for (Marker marker : markerList) {
            if (marker.getIcon() == iconP) {
                lastClick = markerList.indexOf(marker);
            }
            final BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromResource(marker.getIcon());
            cacheBitmap.add(bitmapDescriptor);
            list.add(new MarkerOptions().icon(bitmapDescriptor)
                    .position(new LatLng(marker.getLat(), marker.getLon())));
        }
        if (positionOptions != null) {
            list.add(positionOptions);
        }
        mMapView.getMap().clear();
        mMarkers.clear();
        mMarkers.addAll(mMapView.getMap().addMarkers(list, false));
    }

    public void addInfoWindow (final List<Marker> markerList, InfoWindowAdapter adapter) {
        Log.i(TAG, "addInfoWindow:" + markerList.size());
        for (BitmapDescriptor descriptor : cacheBitmap) {
            if (descriptor == null || descriptor.getBitmap() == null) {
                continue;
            }
            descriptor.getBitmap().recycle();
            descriptor.recycle();
        }
        final ArrayList<MarkerOptions> list = new ArrayList<>();
        for (Marker marker : markerList) {
            final BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromView(adapter.getView(markerList.indexOf(marker)));
            cacheBitmap.add(bitmapDescriptor);
            list.add(new MarkerOptions().icon(bitmapDescriptor)
                    .setFlat(false)
                    .position(new LatLng(marker.getLat(), marker.getLon())));
        }
        if (positionOptions != null) {
            list.add(positionOptions);
        }
        mMapView.getMap().clear();
        mMarkers.clear();
        mMarkers.addAll(mMapView.getMap().addMarkers(list, false));
    }

    public void drawLine (List<LatLon> list, float width, int color) {
        List<LatLng> latLngs = new ArrayList<>();
        for (LatLon latLon : list) {
            latLngs.add(new LatLng(latLon.getLat(), latLon.getLon()));
        }
        final Polyline polyline = mMapView.getMap().addPolyline(new PolylineOptions().
                addAll(latLngs).width(width).color(color));
    }

    public void setZoomLevelListener (OnZoomLevelListener zoomLevelListener) {
        mZoomLevelListener = zoomLevelListener;
    }

    public void setOnMarkerClickListener (OnMarkerClickListener onMarkerClickListener) {
        mOnMarkerClickListener = onMarkerClickListener;
    }

    public void setZoomLevel (float level) {
        Log.i(TAG, "setZoomLevel");
        mMapView.getMap().moveCamera(CameraUpdateFactory.zoomTo(level));
    }

    /**
     * 显示当前位置信息
     *
     * @param location
     */
    public void showLocation (Location location) {
//        MyLocationData locData = new MyLocationData.Builder()
//                .accuracy(location.getRadius())
//                // 此处设置开发者获取到的方向信息，顺时针0-360
//                .direction(location.getDirection()).latitude(location.getLatitude())
//                .longitude(location.getLongitude()).build();
//        mMapView.getMap().setMyLocationConfiguration(new MyLocationConfiguration(MyLocationConfiguration.LocationMode.NORMAL, false, searchBdA));
//        mMapView.getMap().setMyLocationData(locData);
    }

    public void onCreate (Bundle savedInstanceState) {
        mMapView.onCreate(savedInstanceState);
    }

    public void onSaveInstanceState (Bundle outState) {
        //在activity执行onSaveInstanceState时执行mMapView.onSaveInstanceState (outState)，保存地图当前的状态
        mMapView.onSaveInstanceState(outState);
    }

    public void onResume () {
        //在activity执行onResume时必须调用mMapView. onResume ()
        mMapView.onResume();
    }

    public void onPause () {
        //在activity执行onPause时必须调用mMapView. onPause ()
        mMapView.onPause();
    }

    public void onDestroy () {
        //在activity执行onDestroy时必须调用mMapView.onDestroy()
        mMapView.onDestroy();
    }

    public interface OnMarkerClickListener {
        void onMarkerClick (int position);
    }

    public interface OnMapClickListener {
        void OnMapClick (double lat, double lon);
    }

    public interface OnZoomLevelListener {
        void onZoomChange (int level, double lat, double lon);
    }


    public interface InfoWindowAdapter {
        View getView (int index);
    }

}
